# @author: Samuel Taylor <samtaylor.uk@gmail.com>
# @package: winecellar
# @license: GNU GPLv3
#
# Copyright (C) 2010  Samuel Taylor <samtaylor.uk@gmail.com>
#----------------------------------------------------------------------
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#-----------------------------------------------------------------------

__author__ = 'Samuel Taylor <samtaylor.uk@gmail.com>'

import sys
from optparse import OptionParser
import time
from progressbar import ProgressBar, Percentage, Bar, ETA, FileTransferSpeed, \
     RotatingMarker, ReverseBar, SimpleProgress
from WineCellar.RepositoryManager import RepositoryManager
from WineCellar.BottleManager import BottleManager
from WineCellar.Bottle import Bottle
from WineCellar.ApplicationPack import ApplicationPack
import WineCellar.Logger
import WineCellar.Config

RepositoryManager = RepositoryManager()
BottleManager = BottleManager()

def doPrint(text):
    print text

def checkCD(appPack, name):
    if appPack.cdCheck() == False:
        doPrint("Error: "+name+" CD is not in the CD Drive.")
        doPrint("Please insert the correct CD and retry")
        doPrint("If you do have the correct CD in the drive, this could be just a bug with the package. You can override the check.")

        qCDCheck = raw_input("(R)etry/(O)verride/(C)ancel [r/o/c]: ")
        
        while qCDCheck != 'r' and qCDCheck != 'R' and qCDCheck != 'o' and qCDCheck != 'O' and qCDCheck != 'c' and qCDCheck != 'C':
            doPrint("Incorrect Option!")
            qCDCheck = raw_input("(R)etry/(O)verride/(C)ancel [r/o/c]: ")

        if qCDCheck == 'r' or qCDCheck == 'R':
            return checkCD(appPack, name)
        elif qCDCheck == 'o' or qCDCheck == 'O':
            return "overide"
        elif qCDCheck != 'c' or qCDCheck != 'C':
            return False
    else:
        return True

def updateDownload(blocks, blockSize, totalSize):
    global pBar
    currentSize = int(blocks*blockSize)
    
    if blocks == 0:
        widgets = [FileTransferSpeed(),' <<<', Bar(), '>>> ', Percentage(),' ', ETA()]
        #widgets = [Percentage(), ' ', Bar(marker=RotatingMarker()),' ', ETA(), ' ', FileTransferSpeed()]
        pBar = ProgressBar(widgets=widgets, maxval=totalSize).start()
        
    if int(totalSize) < currentSize:
        currentSize = int(totalSize)
        pBar.finish()
        print
    pBar.update(currentSize)

def updateFile(currentFile, totalFile):
    doPrint("Downloading file "+str(currentFile)+" of "+str(totalFile))

def updateAppFile(currentFile, totalFile):
    if currentFile == 1:
        doPrint("Downloading required files for Application")
    doPrint("Downloading file "+str(currentFile)+" of "+str(totalFile))


def installPack(shortname, bottle=None):
    global RepositoryManager
    global BottleManager
    global ApplicationPack
    #RepositoryManager = RepositoryManager()
    

    appInfo = RepositoryManager.findApplication(shortname)

    if appInfo == False:
        doPrint("Error: No application found in Repositories")
        doPrint("Try updating repositories. Run: "+sys.argv[0]+" update")
    else:
        name = appInfo[0]["name"]
        doPrint("Downloading Package")
        if RepositoryManager.downloadPackage(appInfo[0]["url"], appInfo[0]["package"], appInfo[0]["repositoryID"], updateDownload) == False:
            doPrint("Error: Failed to download package")
            doPrint("Try updating repositories. Run: "+sys.argv[0]+" update")
        else:
            selfApplicationPack = ApplicationPack(appInfo[0]["path"], shortname)
            
            if selfApplicationPack.isCrackRequired():
                doPrint("Warning: "+name+" requires a crack to run correctly. Cracks maybe ilegal in some countries.")
                doPrint("It's down to you to find out if you can use cracks legally in your country.")
                
                qCDCheck = raw_input("Continue? [y/n]: ")
                while qCDCheck != 'n' and qCDCheck != 'N' and qCDCheck != 'Y' and qCDCheck != 'y':
                    doPrint("Incorrect Option!")
                    qCDCheck = raw_input("Continue? [y/n]: ")

                if qCDCheck == 'N' or qCDCheck == 'n':
                    return
            
            cdResult = checkCD(selfApplicationPack, appInfo[0]["name"])
            if cdResult == False:
                return
            elif cdResult == "overide":
                cdOveride = True
            
            if bottle == None:
                doPrint("Creating Bottle for "+name)
                if BottleManager.create(shortname) == False:
                    doPrint("Error: Failed to create bottle.")
                    return
                bottle = shortname
            else:
                selfApplicationPack.setBottle(bottle)
            
            for depends in selfApplicationPack.getDependences().iteritems():
                doPrint("Installing dependence "+str(depends[1]["shortname"])+" for "+name)
                installPack(depends[1]["shortname"], bottle)

            selfApplicationPack.download(updateAppFile, updateDownload)
            doPrint("Installing "+name)
            selfApplicationPack.installer()
            doPrint("Finished Installing "+name)

def usage():
	print "Usage: "+sys.argv[0]+" [options] COMMAND [command options]"
	print "Commands:"
	print "  update             Update local repositories from online repositories."
	print "  install [package]  Install package from repositories."

def version():
	print "winecellar "+Config.__version__

def start():
    parser = OptionParser()
    parser.add_option("-d", "--debug", help="Set logging level to debug", action="store_true", dest="debug")
    
    (options, args) = parser.parse_args()
    if options.debug:
        Logger.setDebug()

    Logger.setDebug()

    if len(sys.argv) > 1:
        if sys.argv[1] == "update":
            doPrint("Updating Repositories")
            RepositoryManager.update(updateFile, updateDownload)
        elif sys.argv[1] == "version":
        	version()
        elif len(sys.argv) == 3 and sys.argv[1] == "install":
            installPack(sys.argv[2])
        else:
    		usage()
    else:
    	usage()
